<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- <div id="back"></div> -->
    <!-- built files will be auto injected -->
    <script>
      /* 
        什么是 SPA 应用
        HTML5 History API https://developer.mozilla.org/zh-CN/docs/Web/API/History_API
        这个 API 帮助我们可以在不刷新页面的前提下 动态改变浏览器地址栏中 URL 地址，动态修改页面上所显示资源
        使用 history API 做的一个小例子的网址 https://codesandbox.io/s/gallant-newton-kl9hj?file=/src/index.js:129-131
        
        SPA 的优点
          1. 速度快，第一次下载完成静态文件，跳转不需要再次下载静态文件
          2. 体验好，整个交互式趋于无缝的，更倾向于原应用
          3. 为前后端分离提供了实践场所

        router-link 跳转方式
        我们第一种方法可以将 to 改成不是字符串类型 ，而是 object 类型，
        这个 object 应该有你要前往的 route 的 name  还有对应的 params
        :to="{ name: 'column', params: { id: 123 } }"

        第二种 我们可以在里面传递一个模板字符串
        :to="`/column/${123}`"

        以上是用的是路由跳转

        我们还可以使用路由里面钩子函数 useRouter

        状态管理工具
        直接使用全局对象存在的问题
          1. 全局对象里面数据是普通的 js 数据类型，他们不是响应式的，也就是第一次读取渲染的时候可能是没有问题的
            但是当数据修改以后，界面没办法做出相应的更新
          2. 全局对象的修改的无法追踪，也就是说应用中的任何一处代码，都有可能有机会拿到全局数据，并做出对应的修改
            ，但是我们没有办法是到是 那块儿代码 那个文件修改了我们的全局数据，这样的话就很容易产生 bug，而且难以追踪
          3. vue 是组件化的世界，组件的构成就像一棵树一样，全局数据一般是从父组件一层一层的传递给子组件，直接
            从一个组件获取数据被视为反模式，这样容易造成数据的混乱

        状态管理三杰
        VueX: https://vuex.vuejs.org/zh/guide/
        ReduX: https://redux.js.org/
        MobX: https://mobx.js.org/README.html

        设计理念
         1. 一个类似 object 的全局数据结构  --- store
         2. 只能调用特定的方法来完成数据的更改

         每一个 VueX 应用的核心就是 store (仓库) ,'store' 基本上是一个容器，它包含着
         你应用中大部分的状态 (state) 

         VueX 和 单纯的全局对象有什么不同
          1. VueX 的状态存储是响应式的。当 vue 组件 从 store 读取状态的时候，如果 store 中的状态发生改变，
              那么相应的的组件也会得到相应的更新
          2. 不能直接更改 store 中的状态，改变 store 中的状态的唯一途径就是显式的提交 (commit) mutations。
              这样使得我们可以方便的跟踪每一个状态，从而让我们能够实现一些工具帮助我们更好的了解我们的应用


        每个路由钩子 都有三个参数
        to: 即将要进入的路由目标
        from: 当前导航正在离开路由
        next: function 这个是一个必须需要调用的方法

        路由导航守卫
          路由守卫有三种
            1. 全局钩子：beforeEach、beforeResolve、afterEach
            2. 独享守卫: (单个路由里面的钩子) beforeEnter、beforeLeave
            3. 组件内的守卫：befoerRouteEnter、beforeRouteUpdate、beforeRouteLeave
          全局守卫
            router.beforeEach() 进入之前触发
            router.afterEach() 进入之后触发
            前置路由守卫(每次切换之前被调用)
            后置路由守卫(每次切换之后被调用)
          独享守卫(某一个路由所单独独享的路由守卫) 只有前置没有后置
          组件内的守卫(某一个组件所单独独享的路由守卫) 只有前置没有后置 直接写在.vue文件当中就可以


          RESTful API 是目前比较成熟的一套互联网应用程序的 API 的设计理念

          动词
            GET(SELECT)：从服务器取出资源
            POST(CREATE)：在服务器新建一个资源
            PUT(UPDATE)：在服务器更新资源
            PATCH(UPDATE)：在服务器更新资源
            DELETE(DELETE)：从服务器删除资源

          常见状态码
          200 OK - [GET]：服务器成功的返回了用户请求的数据
          204 NO CONTENT - [DELETE]：用户删除数据成功
          401：表示用户没有权限
          403：表示用户得到了授权，但是访问是被禁止的
          404：用户发出的请求针对的是不存在的记录，服务器没有进行操作


        axios拦截器 (interceptors)
          axios拦截器主要分为两种：请求拦截器和响应拦截器

          请求拦截器
          发送请求时，拦截用户的请求，执行完一系列的处理在发送出去(添加 cookie、token、请求头等)
          axios.interceptors.request.use(
            req => {} // 对发起的请求进行处理 ，req是请求的参数
            err => {} // 出现请求错误的进行处理
          )

          axios.interceptors.request.use(
            config => {
              const token = localStorage.getItem('token')
              if(token) { // 不为空的话就设置进 headers
                config.headers['token'] = token
              }
              return config
            }
            err => {
              return Promise.reject(error)
            }
          )

          响应拦截器
          当服务器产生响应式，对响应的数据进行拦截，并对拦截的数据进行处理，如果出错的话，就返回
          错误信息，并用 message 显示错误

          axios.interceptors.response.use(
            res => {} // 对响应进行处理 ，req返回的数据
            err => {} // 出现请求错误的进行处理
          )

          {
            "code": 0,
            "desc": 'Success'
            "data": "xxxxxx"
          }

          axios.interceptors.response.use(
            res => {
              if(res.code === 0) {
                return Promise.resolve(res.data)
              } else {
                ELMessage({
                  message: 'Error',
                  type: 'error'
                })
                return Promise.reject(new Error('Error Message'))
              }
            },
            err => {
              ELMessage({
                message: err.data.message,
                type: 'error'
              })
            }
          )


          上传文件的两种方式

          第一种使用传统的 from submission，表单提交的方式
          第二种是使用 js 发送异步请求的方式

          传统表单模式
          <form method="post" cencType="multipart/form-data" action="https://jsonplaceholder.typicode.com">
            <input type="file" />
            <button type="submit">Submit</button>
          </form>

          使用异步请求文件上传

      */

    </script>
  </body>
</html>
